/*************************************************************/
/*   Headers for a neo-hookean elasticity tensor in MOOSE    */
/*                  Status: not working                      */
/*                                                           */
/* Copyright (C) 2018  eDgar                                 */
/*                                                           */
/* This program is free software: you can redistribute it    */
/* and/or modify it under the terms of the GNU General       */
/* Public License as published by the Free Software          */
/* Foundation, either version 3 of the License, or (at your  */
/* option) any later version.                                */
/*                                                           */
/* This program is distributed in the hope that it will be   */
/* useful, but WITHOUT ANY WARRANTY; without even the        */
/* implied warranty of MERCHANTABILITY or FITNESS FOR A      */
/* PARTICULAR PURPOSE.  See the GNU General Public License   */
/* for more details.                                         */
/*                                                           */
/* You should have received a copy of the GNU General Public */
/* License along with this program.  If not, see             */
/* <http://www.gnu.org/licenses/>.                           */
/*************************************************************/

// Lines like this (starting with //) are extra documentation

// This line is a conditional to make sure that the function
// is not declared twice (it ends with #endif below;
// everything in-between is within the conditional if it's
// true)
#ifndef COMPUTEELASTICITYTENSORNEOHOOKEAN_H
// After making sure that the function hasn't been
// previously defined, we state that we are now going to
// define it
#define COMPUTEELASTICITYTENSORNEOHOOKEAN_H

// We are going to use functions to define the elasticity tensor
// (a material needs an elasticity, strain and stress tensors),
// so we load (include, import) it at compilation time.
// This class provides, among others, _elasticity_tensor (a
// RankFourTensor MaterialProperty--Andrew Wilkins)
#include "ComputeElasticityTensorBase.h"
#include "RankTwoTensor.h"

// State what we are creating so that the App is found when
// doing the registration
class ComputeElasticityTensorNeohookean;

// ... and declare a (MOOSE) template for it
template <>
InputParameters
validParams<ComputeElasticityTensorNeohookean>();

/**
 * ComputeElasticityTensorNeohookean defines an elasticity
 * tensor for the neo-hookean material.
 *
 *
 *  LaTeX:
 *  c_{ijkl} = \frac{\lambda}{J}
 *                 \cdot\delta_{ij}\cdot\delta_{kl}
 *                 + \frac{
 *                    \mu - \lambda \cdot \ln\left(
 *                      J\right)}{J} \cdot \left(
 *                        \delta_{ik}\cdot\delta_{jl}
 *                        + \delta_{il}\cdot\delta_{kj}
 *                \right)
 *
 *  - Belytschko, T., Liu, W. K., Moran, B., & Elkhodary,
 *    K. (2014). Nonlinear finite elements for continua and
 *    structures. : John Wiley and Sons, Ltd.
 *
 *  c_ijkl = 1 / J * (lambda_0 * delta_ij * delta_kl
 *                    + (mu_0 - lambda_0 * log(J))
 *                      * 2 * (delta_ik * delta_jl
 *                             + delta_il * delta_kj));
 *
 * */

// State what we are creating.
// We inherit from ComputeElasticityTensorBase, which
// "declares a RankFourTensor MaterialProperty called
// _elasticity_tensor that you need to populate with values
// in your computeQpElasticityTensor method"
// (andrew.wilkins)
class
ComputeElasticityTensorNeohookean :
  public ComputeElasticityTensorBase
{
public:
  ComputeElasticityTensorNeohookean
  (const InputParameters & parameters);

protected:
  // - Qp refers to quadrature points
  //   - This function "Assign{s an} elasticity tensor at a
  //     given given quad point", [see
  //     ComputeElasticityTensor.C, 2017-11-01]
  // - `override' means to make sure that you inherit the
  //   right thing (something that exists)
  virtual void computeQpElasticityTensor() override;

  // // Something that belongs to your object goes with _,
  // // but the program will run without it.
  // // We can declare a constant, for instance
  // const Real & _some_constant;

  // Following the style in,
  // [[moose/modules/tensor_mechanics/include/materials/ComputeIsotropicElasticityTensor.h]]
  // create Booleans which will be used to test if the
  // material constants were defined in the .i (input) file
  // They become constants and pointers when the constructor
  // is defined (see ComputeElasticityTensorNeohookean.C):
  // (const InputParameters & parameters)
  const bool _lambda_set;
  const bool _mu_set;
  const bool _nu_set;
  const bool _E_set;

  // These are just material properties which don't change
  /**
   * Lamé constants \lambda and \mu: \lambda > 0, \mu > 0
   */
  Real _lambda;
  Real _mu;
  /**
   * Poisson's ratio and Young's modulus: -1 < \nu < 0.5,
   *  E > 0
   */
  const Real _nu;
  const Real _E;

  // We state that this class has a fourth order tensor
  // called _c_ijkl (we could have used another name; not
  // even the indices are required)
  /* Spatial elasticity tensor */

  // !! Consider ElasticityTensorR4
  RankFourTensor _c_ijkl;

  // I will try to use the deformation gradient from
  // ComputeFinitestrain, in a similar way as it is done in
  // FiniteStrainCrystalPlasticity
  const
  MaterialProperty<RankTwoTensor> & _deformation_gradient;

  // "You can declare material property for J_1 in the
  // ComputeElasticityTensorNeohookean.C and get material
  // property J_1 in ComputeStressNeohookean.C." --Wen Jiang
  /* Inverse and natural logarithm of the determinant of the
     deformation gradient */
  MaterialProperty<Real> & _J_1;
  MaterialProperty<Real> & _logJ;
};

// This indicates that the conditional finished, and a tag
// is next to it to identify which "if" it closes (there
// could be nested conditionals, and they become difficult
// to track).
#endif // COMPUTEELASTICITYTENSORNEOHOOKEAN_H
